﻿using System;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using DbGenerator.Factory.events;
using Unity.Test.Performance.timer;
using DbGenerator.Model.units.database;
using System.Threading;
using System.Data.SqlClient;
using DbGenerator.Factory.generator;

namespace DbGenerator.Test.WinUI
{
    public delegate void DGenerationCompleted(TFactoryArgs args);
    public delegate void DReadDatabaseCompleted(TFactoryArgs args);
    public delegate void DDisposed();
    public delegate void DUCDisposed();

    public partial class TDbGenerationUC : UserControl
    {
        public TDbGenerationUC()
        {
            InitializeComponent();
            pbGeneration.Value = pbGeneration.Minimum;
            _GeneArgs = new TFactoryArgs();
            _GeneArgs.GenerationTurtle.Events.TimerRunning +=
                new DTimerRunningEventHandler(Events_TimerRunning);
            _GeneArgs.ReadTurtle.Events.TimerRunning += new DTimerRunningEventHandler(Events_TimerRunning);
            txtServer.Text = Environment.MachineName + "\\SQLEXPRESS";
            ReadCompletedEvent += new DReadDatabaseCompleted(TDbGenerationUC_ReadCompletedEvent);
            GenerationCompletedEvent += new DGenerationCompleted(TDbGenerationUC_GenerationCompletedEvent);
            CheckForIllegalCrossThreadCalls = false;

        }

        void TDbGenerationUC_GenerationCompletedEvent(TFactoryArgs args)
        {
            if (MessageBox.Show("Generation Completed. Ready to Read Database?"
                , "Information", MessageBoxButtons.OKCancel
                , MessageBoxIcon.Information) == DialogResult.OK)
            {
                if (!cbxCreateConcrete.Checked)
                {
                    txtDatabaseName.BackColor = Color.FromKnownColor(KnownColor.Control);
                    if (!String.IsNullOrEmpty(txtDatabaseName.Text))
                    {
                        _GeneArgs.Database = new TDatabase(txtDatabaseName.Text);
                    }
                    else
                    {
                        txtDatabaseName.BackColor = Color.Red;
                        MessageBox.Show("You must set database name."
                            , "Error", MessageBoxButtons.OK
                            , MessageBoxIcon.Error);
                        this.Enabled = true;
                        return;
                    }
                }
                pbGeneration.Value = pbGeneration.Minimum;
                Thread tRead = new Thread(new ThreadStart(ReadHandler));
                tRead.Start();
            }
        }

        void TDbGenerationUC_ReadCompletedEvent(TFactoryArgs args)
        {
            MessageBox.Show("Read Completed", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
            this.Enabled = true;
        }

        public event DGenerationCompleted GenerationCompletedEvent;
        public event DReadDatabaseCompleted ReadCompletedEvent;
        public event DDisposed FormDisposedEvent;
        private TFactoryArgs _GeneArgs;
        private string _FullPath;

        public TFactoryArgs GeneArgs
        {
            get { return _GeneArgs; }
        }

        void Events_TimerRunning(TTimerRunningEventArgs args)
        {
            pbGeneration
                .Increment(Convert.ToInt32(Convert.ToDouble(pbGeneration.Maximum) * args.CompletionRatio));
        }


        private void btnFBDConcreteModule_Click(object sender, EventArgs e)
        {
            if (ofdConcreteDll.ShowDialog() == DialogResult.OK)
            {
                _FullPath = ofdConcreteDll.FileName;
                lblConcreteModuleName.Text = _FullPath.Substring(_FullPath.LastIndexOf("\\") + 1);
                _GeneArgs.EntityFolderPath = _FullPath.Substring(0, _FullPath.LastIndexOf("\\") + 1);
                gbxConnectionString.Visible = true;
            }
        }
        private void cbxDropDatabase_CheckedChanged(object sender, EventArgs e)
        {
            _GeneArgs.DropDatabase = cbxDropDatabase.Checked;
        }
        private SqlConnection approvedConnection = null;
        private void btnTestConnection_Click(object sender, EventArgs e)
        {
            SqlConnection connection =
                new SqlConnection(GenerateConnectionString());
            try
            {
                connection.Open();
                btnApproveConnection.Enabled = true;
                approvedConnection = connection;
                ttpTestConnectionSuccessful.Active = true;
            }
            catch
            {
                btnApproveConnection.Enabled = false;
                ttpTestConnectionSuccessful.Active = false;
                MessageBox.Show("Connection Arguments Invalid.\nTry Again."
                    , "Error"
                    , MessageBoxButtons.OK
                    , MessageBoxIcon.Error);
            }
            finally
            {
                if (connection.State == ConnectionState.Open)
                    connection.Close();
            }
        }
        private string GenerateConnectionString()
        {
            string r = String.Format("Server={0};Initial Catalog={1};"
                , txtServer.Text, txtInitialCatalog.Text);
            if (cbxTrustedConnection.Checked)
                return r + "Trusted_Connection=True;";
            else
                return String.Format("{0}User Id={1};Password={2}"
                    , r, txtUserId.Text, txtPassword.Text);
        }
        private void cbxTrustedConnection_CheckedChanged(object sender, EventArgs e)
        {
            pnlAuthenticatedConnection.Enabled = !cbxTrustedConnection.Checked;
        }
        private void btnApproveConnection_Click(object sender, EventArgs e)
        {
            gbxGeneration.Visible = true;
            txtDatabaseName.Visible = !cbxCreateConcrete.Checked;
            cmbDatabaseNames.Visible = cbxCreateConcrete.Checked;
            if (cbxCreateConcrete.Checked)
            {
                SqlCommand command = new SqlCommand("USE master; SELECT [name] FROM sys.databases", approvedConnection);
                SqlDataAdapter da = new SqlDataAdapter(command);
                DataTable dt = new DataTable();
                da.Fill(dt);
                cmbDatabaseNames.DataSource = null;
                cmbDatabaseNames.DisplayMember = "name";
                cmbDatabaseNames.ValueMember = "name";
                cmbDatabaseNames.DataSource = dt;
            }
            _GeneArgs.MasterConnection = approvedConnection;
        }
        private void btnGenerateDatabase_Click(object sender, EventArgs e)
        {
            pbGeneration.Value = pbGeneration.Minimum;
            if (cbxCreateConcrete.Checked)
            {
                if (cmbDatabaseNames.SelectedIndex == -1)
                {
                    MessageBox.Show("Please Select a Database.");
                    return;
                }
                this.Enabled = false;
                _GeneArgs.Database = new TDatabase(cmbDatabaseNames.SelectedValue.ToString());
                Thread tConcrete = new Thread(new ThreadStart(CreateConcreteHandler));
                tConcrete.Start();
            }
            else if (!String.IsNullOrEmpty(txtDatabaseName.Text))
            {
                this.Enabled = false;
                _GeneArgs.Database = new TDatabase(txtDatabaseName.Text);
                _GeneArgs.AssemblyName = GetConcreteModuleName();
                pbGeneration.Value = pbGeneration.Minimum;
                Thread tGeneration = new Thread(new ThreadStart(GenerateHandler));
                tGeneration.Start();
            }
            else if (cmbDatabaseNames.SelectedIndex != -1)
            {
                this.Enabled = false;
                _GeneArgs.Database = new TDatabase(cmbDatabaseNames.SelectedValue.ToString());
                pbGeneration.Value = pbGeneration.Minimum;
                Thread tGeneration = new Thread(new ThreadStart(GenerateHandler));
                tGeneration.Start();
            }
            else
                txtDatabaseName.BackColor = Color.Red;
            cmbDatabaseNames.Enabled = false;
            txtDatabaseName.Enabled = false;
        }

        private string GetConcreteModuleName()
        {
            if (!cbxCreateConcrete.Checked)
                return _FullPath.Substring(_FullPath.LastIndexOf("\\") + 1).Replace(".dll", "");
            else
                return "DbGenerator.Concrete." + cmbDatabaseNames.SelectedValue.ToString();
        }


        private void cmbUserSettings_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbUserSettings.SelectedIndex == -1)
                return;
            if (cmbUserSettings.SelectedItem.ToString() == "dr.ozgur.sonmez-work")
            {
                txtDatabaseName.BackColor = Color.FromKnownColor(KnownColor.Control);
                cbxDropDatabase.Checked = true;
                txtServer.Text = Environment.MachineName;
                cbxTrustedConnection.Checked = false;
                txtUserId.Text = "sa";
                txtPassword.Text = "logo";
                txtDatabaseName.Text = "db2";
                this.PerformLayout();
            }
        }

        private void ReadHandler()
        {
            SDbFactory.ReadFromScratch(_GeneArgs);
            if (ReadCompletedEvent != null)
                ReadCompletedEvent(_GeneArgs);
        }

        private void GenerateHandler()
        {
            SDbFactory.GenerateFromScratch(_GeneArgs);
            if (GenerationCompletedEvent != null)
                GenerationCompletedEvent(_GeneArgs);
        }

        private void CreateConcreteHandler()
        {
            SDbFactory.CreateConcrete(_GeneArgs);
            if (GenerationCompletedEvent != null)
                GenerationCompletedEvent(_GeneArgs);
        }

        private void btnDispose_Click(object sender, EventArgs e)
        {
            if (FormDisposedEvent != null)
                FormDisposedEvent();
        }

        private void cbxCreateConcrete_CheckedChanged(object sender, EventArgs e)
        {
            btnFBDConcreteModule.Enabled =
                cbxDropDatabase.Enabled = !cbxCreateConcrete.Checked;
            gbxConnectionString.Visible = cbxCreateConcrete.Checked;
            if (cbxCreateConcrete.Checked)
                lblConcreteModuleName.Text = "DbGenerator.Concrete.Standart.dll";
            else
                lblConcreteModuleName.Text = "Dependent on Db Name.";

            if (cbxCreateConcrete.Checked)
                _GeneArgs.EntityFolderPath = Application.StartupPath;
        }

        private void cmbDatabaseNames_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbDatabaseNames.SelectedIndex != -1)
            {
                _GeneArgs.AssemblyName = GetConcreteModuleName();
            }
        }
    }
}
